﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace VBGBuilder {
  class DLG {
    private DirectoryInfo _root;
    private FileInfo _appQA;
    private Dictionary<String,VBFile> _files;
    private String _svnURL;
    private SVNFactory _svn;

    public DLG(DirectoryInfo  root) {
      _root = root;
      _files = new Dictionary<String,VBFile>(50);
    }

    public DirectoryInfo root {
      get { return _root; }
    }

    public VBFile getVBFile(String filePath) {
      Boolean isVBP = false;

      if (_files.ContainsKey(filePath)) {
        return _files[filePath];
      }
      VBFile vbFile;
      if (filePath.EndsWith(".vbp", StringComparison.OrdinalIgnoreCase)) {
        vbFile = new VBPFile(this, filePath);
        isVBP = true;
      }
      else {
        vbFile = new VBFile(this, filePath);
      }
      _files.Add(filePath, vbFile);

      _svn.update(vbFile, isVBP);

      if (isVBP) {
        VBPFile vbp = (VBPFile)vbFile;
        vbp.parse();
      }

      return vbFile;
    }

    public static String getFullPath(String parent, String child) {
      return parent  + "\\" + child ;
    }

    public String svnURL {
      set { _svnURL = value; }
      get { return _svnURL; }
    }

    public SVNFactory svn {
      set { _svn = value; }
    }
  }

  class VBFile {
    protected String _filePath;
    protected FileInfo _vbFile;
    protected DLG _dlg;

    public VBFile() {
    }

    public VBFile(DLG dlg, String filePath) {
      _dlg = dlg;
      this.filePath = filePath;
    }

    public String filePath {
      get { return _filePath; }
      set {
        _filePath = value;
        _vbFile = new FileInfo(dlg.root.FullName + "\\"+ filePath);
      }
    }

    public FileInfo file {
      get { return _vbFile; }
    }

    public DLG dlg {
      get { return _dlg; }
    }

    public String svnURL {
      get {
        return dlg.svnURL + "/" + filePath.Replace("\\","/");
      }
    }

  }

  class VBPFile : VBFile {

    private LinkedList<String> text;

    public VBPFile(DLG dlg, String filePath) {
      _dlg = dlg;
      this.filePath = filePath;
      text = new LinkedList<String>();
    }
    
    private void loadFileTexts() {
      FileStream fs = new FileStream(_vbFile.FullName, FileMode.Open);
      StreamReader r = new StreamReader(fs, Encoding.ASCII);

      for (String str = r.ReadLine(); !r.EndOfStream; str = r.ReadLine()) {
        text.AddLast (str);
      }

      r.Close();
      fs.Close();

    }

    private void parseFileText() {
      foreach (String str in text) {
        String path= getVBFilePath(str);
        if (path == "") {
          continue ;
        }
        path = MergeFilePath(path);
        dlg.getVBFile(path);
      }
    }

    private String getVBFilePath (String str) {
      String[] strs = str.Split('=');
      if (strs.Count() < 2) {
        return "";
      }

      String path = "";
      switch (strs[0].ToUpper() ) {
/*
 * Module=EDateTimeUtils; 
 * ..\..\..\Foundations\Shared\DateTime\Modules\EDateTimeUtils.bas
 * UserControl=LBCvgFOEdit.ctl
 * Class=LBCvgList; LBCvgList.cls
 * */
        case "MODULE":
          strs = strs[1].Split(';');
          if (strs.Count() > 1) {
            path = strs[1].Trim();
          }
          break;
        case "USERCONTROL":
          path = strs[1];
          break;
        case "CLASS":
          strs = strs[1].Split(';');
          if (strs.Count() > 1) {
            path = strs[1].Trim();
          }
          break;
      }
      return path;
    }

    private Boolean readFile() {
      return true;
    }

    public Boolean parse() {
      loadFileTexts();
      parseFileText();
      return true;
    }

    private String MergeFilePath(String path) {
      Char[] seperator = {'\\'};
      String[] child = path.Split(seperator ,StringSplitOptions.RemoveEmptyEntries );
      if (child.Count() < 1) {
        return filePath;
      }

      String[] parent = filePath.Split(seperator , StringSplitOptions.RemoveEmptyEntries);
      int level = 0;
      for (int i = 0; i < child.Count(); i++) {
        if (child[i] == "..") {
          level++;
        }
      }
      String str = "";
      for (int i = 0; i < parent.Count() - level-1; i++) {
        str += (parent[i] + "//");
      }
      for (int i = level; i < child.Count() - 1 && i >-1; i++) {
        str += (child[i] + "//");
      }
      str += child[child.Count()-1];
      return str;
    }

  }
}